package com.genex.server;


import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;

import org.apache.log4j.Logger;

import com.genex.dao.DBbase;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 处理TextWebSocketFrame
 * 
 * @author xuchenzhe
 * @date 2016-12-1 
 */
public class TextWebSocketFrameHandler extends
		SimpleChannelInboundHandler<TextWebSocketFrame> {
	
	private static Logger log = Logger.getLogger(TextWebSocketFrameHandler.class); 
	
	
	public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
	
	public static Map<String,Channel> channerMaps = new HashMap<String,Channel>();
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx,
			TextWebSocketFrame msg) throws Exception { // (1)
		Channel incoming = ctx.channel();
		//消息结构式   消息类型#消息内容 
		// eg:        msg#我爱你
		
		log.info("msg:" +msg.text());
		String[] msgs = new String[]{"msg","不知道你说什么。。"};
		try {
				msgs = msg.text().split("#");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
		
		//处理消息队列
		String result = doevent(ctx,msgs);
		
		if(result !=null){
			//广播消息
			broadcast(result);
		}else{
			log.info("有人输入了什么不得了的东西过来");
		}
		
	}
	
	//广播消息给所有在线用户
	private void broadcast(String result) {
		for (Channel channel : channels) {
			channel.writeAndFlush(new TextWebSocketFrame(result ));
      }
	}

	//处理所有的消息事件
	private String doevent(ChannelHandlerContext ctx,String[] msgs) {
		String msgtype = msgs[0];
		StringBuffer sb = new StringBuffer();
		if(msgtype.equals("msg")){
		  String clientIP = "";
            InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
            clientIP = inSocket.getAddress().getHostAddress();
//        	System.out.println("clientIP=" + clientIP);
			String msgBody = msgs[2];
			if(msgBody.startsWith("你对")&& msgBody.contains("[")&& msgBody.contains("]")){
				String toPepole = msgBody.substring(msgBody.indexOf("[")+1,msgBody.indexOf("]"));
				Channel toChannel = channerMaps.get(toPepole);
				if (toChannel == null) {
				    return null;
                }
                sb.append("privateMsg").append("#[").append(msgs[1]).append("]#").append(msgBody.substring(msgBody.indexOf("说:")+3)).append("#[").append(toPepole).append("]");
                //写入数据库
                DBbase.getDbDao().saveMsg(msgs[1], msgs[2],clientIP);
                String text = sb.toString();
                toChannel.writeAndFlush(new TextWebSocketFrame(text));
                Channel channel = ctx.channel();
                channel.writeAndFlush(new TextWebSocketFrame(text));
                return null;
			}
			sb.append("msg").append("#[").append(msgs[1]).append("]#").append(msgs[2]);
			//写入数据库
			DBbase.getDbDao().saveMsg(msgs[1], msgs[2],clientIP);
			return sb.toString();
		}else if(msgtype.equals("nickname")){
			Channel channel = ctx.channel();
			if(!channerMaps.containsKey(msgs[1])){
				channerMaps.put( msgs[1], channel);
			    //写入数据库
				DBbase.getDbDao().saveNickCounts();
				sb.append("sysmsg").append("#系统说你们别吵了，欢迎【"+msgs[1]+"】加入");
				//刷新系统人数
				broadcast("listcount#"+channels.size());
				
				return sb.toString();
			}else{
				//告诉用户已经重名了
				channel.writeAndFlush(new TextWebSocketFrame("nickerror#已经有人叫这名了~" ));
			}
		}
		return null;
	}

	@Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {  // (2)
        Channel incoming = ctx.channel();
        
        // Broadcast a message to multiple Channels
        channels.writeAndFlush(new TextWebSocketFrame("[SERVER] - " + incoming.remoteAddress() + " 加入"));
        
        channels.add(incoming);
      //写入数据库
		DBbase.getDbDao().saveViewCounts();
		System.out.println("Client:"+incoming.remoteAddress() +"加入");
		
		//刷新系统人数
		broadcast("listcount#"+channels.size());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {  // (3)
        Channel incoming = ctx.channel();
        removeChannel(incoming);

        // Broadcast a message to multiple Channels
        channels.writeAndFlush(new TextWebSocketFrame("[SERVER] - " + incoming.remoteAddress() + " 离开"));
		System.out.println("Client:"+incoming.remoteAddress() +"离开");

        // A closed Channel is automatically removed from ChannelGroup,
        // so there is no need to do "channels.remove(ctx.channel());"
    }
	    
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception { // (5)
        Channel incoming = ctx.channel();
		System.out.println("Client:"+incoming.remoteAddress()+"在线");
	}
	
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
        Channel incoming = ctx.channel();
		System.out.println("Client:"+incoming.remoteAddress()+"掉线");
		
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)	// (7)
			throws Exception {
    	Channel incoming = ctx.channel();
		System.out.println("Client:"+incoming.remoteAddress()+"异常");
        // 当出现异常就关闭连接
        cause.printStackTrace();
        ctx.close();
       
        removeChannel(incoming);
	}
	
	//删除channel
	private void removeChannel(Channel incoming){
		for (Map.Entry<String, Channel> entry:channerMaps.entrySet()) {
			if(entry.getValue() .equals(incoming)){
				broadcast( "sysmsg#系统妹子哭了，【"+entry.getKey()+"】离开了我们!");
				channerMaps.remove(entry.getKey());
			}
		}
		
		//刷新系统人数
		broadcast("listcount#"+channels.size());
	
	}

}
